<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>The Table of All Posible Input Within Size 4</title>

  <style>
    body {
      background-color: #1e1e1e;
      color: #dcdcdc;
    }

    #mainTable {
      margin: 1em auto;
      text-align: center;
    }


    #mainTable th {
      width: 6em;
    }

    #mainTable td,
    #mainTable th {
      border-bottom: 1px solid #fff;
    }

    #mainTable code:first-child {
      color: #dc5656;
    }

    #rows span:first-child {
      color: #569cd6;
    }

    #rows span:last-child {
      color: #b8d7a3;
    }
  </style>
</head>

<body>
  <table id="mainTable">
    <thead>
      <tr>
        <th><span style="color: #569cd6;">T</span> ; <span style="color: #b8d7a3;">L</span></th>
        <th><tt>x</tt><br><tt>x</tt></th>
        <th><tt>0</tt><br><tt>0</tt></th>
        <th><tt>0</tt><br><tt>1</tt></th>
        <th><tt>0</tt><br><tt>2</tt></th>
        <th><tt>1</tt><br><tt>0</tt></th>
        <th><tt>1</tt><br><tt>1</tt></th>
        <th><tt>1</tt><br><tt>2</tt></th>
        <th>Diff</th>
        <th>CODE</th>
      </tr>
    </thead>
    <tbody id="rows"> </tbody>
  </table>

  <script src="./machine_plus.js"></script>
  <script>
    const ENDS = [
      { r: '', t: '' },
      { r: '0', t: '0' },
      { r: '0', t: '1' },
      { r: '0', t: '2' },
      { r: '1', t: '0' },
      { r: '1', t: '1' },
      { r: '1', t: '2' }
    ];

    const rows = document.getElementById('rows');
    const size = 5, loop2 = Math.pow(2, size), loop3 = Math.pow(3, size);
    const groups = {};

    fillZero = true;

    (async () => {
      // 单例，减少创建次数
      // Singleton, cut down the Times of create one Set Object
      let diff = [];

      for (let ri = 0; ri < loop2; ri++) {
        for (let ti = 0; ti < loop3; ti++) {
          diff.length = 0;

          let rs = ri.toString(2).padStart(size, '0'),
            ts = ti.toString(3).padStart(size, '0'),
            code = '';

          await new Promise((resolve, reject) => {

            requestAnimationFrame(() => {

              let tr = document.createElement("tr");
              tr.innerHTML += `<th><tt>${rs}</tt><br><tt>${ts}</tt></th>`;

              for (let j = 0; j < ENDS.length; j++) {
                let cnt = 0, wth = 0;

                if (j) {
                  robots = [...Array.from(rs), ENDS[j].r].map(e => +e);
                  track = [...Array.from(ts), ENDS[j].t].map(e => +e);
                } else {
                  robots = Array.from(rs).map(e => +e);
                  track = Array.from(ts).map(e => +e);
                }

                while (robots.some(e => !!e) || track.some((e, i, t) => i <= t.length - 2 && !!e)) {
                  cnt++;
                  wth = Math.max(track.length, wth);

                  // if(cnt === 10000){
                  //   reject(null);
                  // }

                  trip();
                }

                let hx = (cnt << 16) + wth;
                if (!diff.includes(hx)) diff.push(hx);
                code += diff.indexOf(hx);

                tr.innerHTML += `<td><span>${cnt}</span> ; <span>${wth}</span></td>`;
              }

              tr.innerHTML += `<td>${diff.length}</td>`;
              tr.innerHTML += `<td><tt>${code}</tt></td>`;

              if (groups[code] && groups[code].length) {
                groups[code].push({ rs, ts });
              } else {
                groups[code] = [{ rs, ts }];
              }

              // if (diff.size === 7) console.log('%s | %s , %d', rs, ts, diff.size)

              rows.appendChild(tr);

              resolve(null);
            });

          })

        }
      }

      console.log('groups : ', groups);
    })()
  </script>
</body>

</html>